//#########################################################################
//                              WackiEngie
//           Copyright (c) 2014 Marc Wacker. All rights reserved.
//#########################################################################

#pragma once

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cstdarg>
#include <cmath>
#include <time.h>                // for clock()  

#include <memory>

// STL containers
#include <vector>
#include <stack>
#include <map>
#include <string>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <bitset>

// C++11 containers 
// TODO: make sure this works in different compilers compilers
#include <unordered_map>
#include <unordered_set>

// STL algorithms & functions
#include <algorithm>
#include <functional>
#include <limits>

// C++ Stream stuff
#include <fstream>
#include <iostream>
#include <iomanip>
#include <sstream>

namespace WackiEngine
{
	// Standard containers in WackiEngine namespace, for easier access
	template<typename T, typename A = std::allocator<T>>
	using Deque = std::deque<T, A>;

	template<typename T, typename A = std::allocator<T>>
	using Vector = std::vector<T, A>;

	template<typename T, typename A = std::allocator<T>>
	using List = std::list<T, A>;

	template<typename T, typename A = std::allocator<T>>
	using Stack = std::stack<T, std::deque<T, A>>;

	template<typename T, typename A = std::allocator<T>>
	using Queue = std::queue<T, std::deque<T, A>>;

	template<typename T, typename P = std::less<T>, typename A = std::allocator<T>>
	using Set = std::set<T, P, A>;

	template<typename K, typename V, typename P = std::less<K>, typename A = std::allocator<std::pair<const K, V>>>
	using Map = std::map<K, V, P, A>;

	template<typename K, typename V, typename P = std::less<K>, typename A = std::allocator<std::pair<const K, V>>>
	using MultiMap = std::multimap<K, V, P, A>;

	template<typename T, typename H = std::hash<T>, typename C = std::equal_to<T>, typename A = std::allocator<T>>
	using UnorderedSet = std::unordered_set<T, H, C, A>;

	template<typename K, typename V, typename H = std::hash<T>, typename C = std::equal_to<K>, typename A = std::allocator<std::pair<const K, V>>>
	using UnorderedMap = std::unordered_map<K, V, H, C, A>;

	template<typename K, typename V, typename H = std::hash<T>, typename C = std::equal_to<K>, typename A = std::allocator<std::pair<const K, V>>>
	using UnorderedMultimap = std::unordered_multimap<K, V, H, C, A>;



}